/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.tabbedproperties.section;

import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CommandStack;
import org.eclipse.jface.text.Assert;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.views.properties.tabbed.ITabbedPropertyConstants;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
import org.eclipse.uml2.uml.Transition;

import com.cea.papyrus.core.commands.ChangeGraphNodePropertyCommand;
import com.cea.papyrus.core.editor.CommandStackUtils;
import com.cea.papyrus.core.tabbedproperties.PropertyViewSection;
import com.cea.papyrus.diagram.statemachine.helper.EdgeTransitionHelper;
import com.cea.papyrus.diagraminterchange2.di2.GraphEdge;
import com.cea.papyrus.diagraminterchange2.di2.GraphElement;
import com.cea.papyrus.diagraminterchange2.di2.GraphNode;
import com.cea.papyrus.diagraminterchange2.di2.Property;

/**
 * Manages presentation section of Transitions
 *
 * @author David Servat
 * @since 11 apr. 07
 */
public class TransitionPresentationSection extends PropertyViewSection{

	/** The check box show guard. */
	private Button checkBoxShowGuard;

	/** The current guard appearance. */
	private boolean currentGuardAppearance;
	
	/** The show guard listener. */
	private SelectionListener showGuard;
	
	/** The check box show triggers. */
	private Button checkBoxShowTriggers;

	/** The current triggers appearance. */
	private boolean currentTriggersAppearance;
	
	/** The show triggers listener. */
	private SelectionListener showTriggers;
	
	/** The check box show effect. */
	private Button checkBoxShowEffect;

	/** The current effect appearance. */
	private boolean currentEffectAppearance;
	
	/** The show effect listener. */
	private SelectionListener showEffect;
	
	/** The check box show name. */
	private Button checkBoxShowName;
		
	/** The current name appearance. */
	private boolean currentNameAppearance;
	
	/** The show name listener. */
	private SelectionListener showName;
	
	/** The check box show stereotypes. */
	private Button checkBoxShowStereotypes;
		
	/** The current stereotypes appearance. */
	private boolean currentStereotypesAppearance;
	
	/** The show stereotypes listener. */
	private SelectionListener showStereotypes;
	
	/**
	 * Creates the controls.
	 * 
	 * @param tabbedPropertySheetPage the tabbed property sheet page
	 * @param parent the parent
	 */
	public void createControls(final Composite parent, final TabbedPropertySheetPage tabbedPropertySheetPage){
		super.createControls(parent, tabbedPropertySheetPage);
		final Composite composite = this.getWidgetFactory().createFlatFormComposite(parent);
		FormData data;
		
		//show name
		checkBoxShowName = this.getWidgetFactory().createButton(composite, "Show Name", SWT.CHECK);
		data = new FormData();
		data.left = new FormAttachment(0, 100);
		data.top = new FormAttachment(0, 0);
		checkBoxShowName.setLayoutData(data);
		
		showName = new SelectionListener(){
			/**
			 * Widget default selected.
			 * 
			 * @param e the e
			 */
			public void widgetDefaultSelected(SelectionEvent e){}

			/**
			 * Widget selected.
			 * 
			 * @param e the e
			 */
			public void widgetSelected(SelectionEvent e){
				if(umlElement instanceof Transition){
					if((diagramElement != null) && (diagramElement instanceof GraphEdge)){
						Command command = new Command(){
							public void execute(){
								redo();
							}
							
							public void undo(){
								redo();
							}

							public void redo(){
								((GraphNode)((GraphElement)diagramElement).getContained().get(0)).setIsVisible(!((GraphNode)((GraphElement)diagramElement).getContained().get(0)).isIsVisible());							
								refresh();
							}
							
						};
						//execute command
						CommandStack stack = CommandStackUtils.getCommandStack();
						Assert.isNotNull(stack, "Impossible to adapt current editor into a CommandStack");
						stack.execute(command);
					}		
				}
			}
		};
		
		checkBoxShowName.addSelectionListener(showName);
		
		//show stereotypes
		checkBoxShowStereotypes = this.getWidgetFactory().createButton(composite, "Show Stereotypes", SWT.CHECK);
		data = new FormData();
		data.left = new FormAttachment(checkBoxShowName, 20);
		data.top = new FormAttachment(0, 0);
		checkBoxShowStereotypes.setLayoutData(data);
		
		showStereotypes = new SelectionListener(){
			/**
			 * Widget default selected.
			 * 
			 * @param e the e
			 */
			public void widgetDefaultSelected(SelectionEvent e){}

			/**
			 * Widget selected.
			 * 
			 * @param e the e
			 */
			public void widgetSelected(SelectionEvent e){
				if(umlElement instanceof Transition){
					if((diagramElement != null) && (diagramElement instanceof GraphEdge)){
						GraphNode graphNode = (GraphNode) ((GraphEdge)diagramElement).getContained().get(1);
						Property property = graphNode.getProperty(EdgeTransitionHelper.TRANSITION_DISPLAY_STEREOTYPES);
						if(property != null){
							ChangeGraphNodePropertyCommand command;
							if(property.getValue().equals(EdgeTransitionHelper.TRANSITION_DISPLAY)){
								command = new ChangeGraphNodePropertyCommand(property, EdgeTransitionHelper.TRANSITION_NOT_DISPLAY){
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void redo(){
										super.redo();
										refresh();
									}
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void undo(){
										super.undo();
										refresh();
									}
								};
							}
							else{
								command = new ChangeGraphNodePropertyCommand(property, EdgeTransitionHelper.TRANSITION_DISPLAY){
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void redo(){
										super.redo();
										refresh();
									}
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void undo(){
										super.undo();
										refresh();
									}
								};
							}
							//execute command
							CommandStack stack = CommandStackUtils.getCommandStack();
							Assert.isNotNull(stack, "Impossible to adapt current editor into a CommandStack");
							stack.execute(command);
						}
					}		
				}
			}
		};
		
		checkBoxShowStereotypes.addSelectionListener(showStereotypes);
		
		//show guard
		checkBoxShowGuard = this.getWidgetFactory().createButton(composite, "Show Guard", SWT.CHECK);
		data = new FormData();
		data.left = new FormAttachment(checkBoxShowStereotypes, 20);
		data.top = new FormAttachment(0, 0);
		checkBoxShowGuard.setLayoutData(data);
		
		showGuard = new SelectionListener(){
			/**
			 * Widget default selected.
			 * 
			 * @param e the e
			 */
			public void widgetDefaultSelected(SelectionEvent e){}

			/**
			 * Widget selected.
			 * 
			 * @param e the e
			 */
			public void widgetSelected(SelectionEvent e){
				if(umlElement instanceof Transition){
					if((diagramElement != null) && (diagramElement instanceof GraphEdge)){
						GraphNode graphNode = (GraphNode) ((GraphEdge)diagramElement).getContained().get(1);
						Property property = graphNode.getProperty(EdgeTransitionHelper.TRANSITION_DISPLAY_GUARD);
						if(property != null){
							ChangeGraphNodePropertyCommand command;
							if(property.getValue().equals(EdgeTransitionHelper.TRANSITION_DISPLAY)){
								command = new ChangeGraphNodePropertyCommand(property, EdgeTransitionHelper.TRANSITION_NOT_DISPLAY){
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void redo(){
										super.redo();
										refresh();
									}
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void undo(){
										super.undo();
										refresh();
									}
								};
							}
							else{
								command = new ChangeGraphNodePropertyCommand(property, EdgeTransitionHelper.TRANSITION_DISPLAY){
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void redo(){
										super.redo();
										refresh();
									}
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void undo(){
										super.undo();
										refresh();
									}
								};
							}
							//execute command
							CommandStack stack = CommandStackUtils.getCommandStack();
							Assert.isNotNull(stack, "Impossible to adapt current editor into a CommandStack");
							stack.execute(command);
						}
					}		
				}
			}
		};
		
		checkBoxShowGuard.addSelectionListener(showGuard);
				
		//show triggers
		checkBoxShowTriggers = this.getWidgetFactory().createButton(composite, "Show Triggers", SWT.CHECK);
		data = new FormData();
		data.left = new FormAttachment(checkBoxShowGuard, 20);
		data.top = new FormAttachment(0, 0);
		checkBoxShowTriggers.setLayoutData(data);
		
		showTriggers = new SelectionListener(){
			/**
			 * Widget default selected.
			 * 
			 * @param e the e
			 */
			public void widgetDefaultSelected(SelectionEvent e){}

			/**
			 * Widget selected.
			 * 
			 * @param e the e
			 */
			public void widgetSelected(SelectionEvent e){
				if(umlElement instanceof Transition){
					if ((diagramElement != null) && (diagramElement instanceof GraphEdge)){
						GraphNode graphNode = (GraphNode) ((GraphEdge)diagramElement).getContained().get(1);
						Property property = graphNode.getProperty(EdgeTransitionHelper.TRANSITION_DISPLAY_TRIGGERS);
						if(property != null){
							ChangeGraphNodePropertyCommand command;
							if(property.getValue().equals(EdgeTransitionHelper.TRANSITION_DISPLAY)){
								command = new ChangeGraphNodePropertyCommand(property, EdgeTransitionHelper.TRANSITION_NOT_DISPLAY){
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void redo(){
										super.redo();
										refresh();
									}
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void undo(){
										super.undo();
										refresh();
									}
								};
							}
							else{
								command = new ChangeGraphNodePropertyCommand(property, EdgeTransitionHelper.TRANSITION_DISPLAY){
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void redo(){
										super.redo();
										refresh();
									}
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void undo(){
										super.undo();
										refresh();
									}
								};
							}
							//execute command
							CommandStack stack = CommandStackUtils.getCommandStack();
							Assert.isNotNull(stack, "Impossible to adapt current editor into a CommandStack");
							stack.execute(command);
						}
					}		
				}
			}
		};
		
		checkBoxShowTriggers.addSelectionListener(showTriggers);
		
		//show effect
		checkBoxShowEffect = this.getWidgetFactory().createButton(composite, "Show Effect", SWT.CHECK);
		data = new FormData();
		data.left = new FormAttachment(checkBoxShowTriggers, 20);
		data.top = new FormAttachment(0, 0);
		checkBoxShowEffect.setLayoutData(data);
		
		showEffect = new SelectionListener(){
			/**
			 * Widget default selected.
			 * 
			 * @param e the e
			 */
			public void widgetDefaultSelected(SelectionEvent e){}

			/**
			 * Widget selected.
			 * 
			 * @param e the e
			 */
			public void widgetSelected(SelectionEvent e){
				if(umlElement instanceof Transition){
					if ((diagramElement != null) && (diagramElement instanceof GraphEdge)){
						GraphNode graphNode = (GraphNode) ((GraphEdge)diagramElement).getContained().get(1);
						Property property = graphNode.getProperty(EdgeTransitionHelper.TRANSITION_DISPLAY_EFFECT);
						if(property != null){
							ChangeGraphNodePropertyCommand command;
							if(property.getValue().equals(EdgeTransitionHelper.TRANSITION_DISPLAY)){
								command = new ChangeGraphNodePropertyCommand(property, EdgeTransitionHelper.TRANSITION_NOT_DISPLAY){
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void redo(){
										super.redo();
										refresh();
									}
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void undo(){
										super.undo();
										refresh();
									}
								};
							}
							else{
								command = new ChangeGraphNodePropertyCommand(property, EdgeTransitionHelper.TRANSITION_DISPLAY){
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void redo(){
										super.redo();
										refresh();
									}
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void undo(){
										super.undo();
										refresh();
									}
								};
							}
							//execute command
							CommandStack stack = CommandStackUtils.getCommandStack();
							Assert.isNotNull(stack, "Impossible to adapt current editor into a CommandStack");
							stack.execute(command);
						}
					}		
				}
			}
		};
		
		checkBoxShowEffect.addSelectionListener(showEffect);
		
		//label of the section
		CLabel transitionPresentationLabel = this.getWidgetFactory().createCLabel(composite, "Display Options:");
		data = new FormData();
		data.left = new FormAttachment(0, 0);
		data.right = new FormAttachment(checkBoxShowName, -ITabbedPropertyConstants.HSPACE);
		data.top = new FormAttachment(checkBoxShowName, 0, SWT.CENTER);
		transitionPresentationLabel.setLayoutData(data);
	}

	/**
	 * Refreshes the view.
	 */
	@Override
	public void refresh(){
		if(!checkBoxShowName.isDisposed() && !checkBoxShowGuard.isDisposed() && !checkBoxShowEffect.isDisposed() && !checkBoxShowStereotypes.isDisposed()){
			//remove all listeners
			checkBoxShowName.removeSelectionListener(showName);
			checkBoxShowGuard.removeSelectionListener(showGuard);
			checkBoxShowEffect.removeSelectionListener(showEffect);
			checkBoxShowTriggers.removeSelectionListener(showTriggers);
			checkBoxShowStereotypes.removeSelectionListener(showStereotypes);
			
			if((diagramElement != null) && (((GraphElement)diagramElement).getSemanticModel() != null)){
				if(umlElement instanceof Transition){
					if(diagramElement instanceof GraphEdge){
						currentNameAppearance = ((GraphNode)((GraphEdge)diagramElement).getContained().get(0)).isIsVisible();
						
						Property property;
						GraphNode graphNode = (GraphNode)((GraphEdge)diagramElement).getContained().get(1);
						if(((Transition)umlElement).getGuard() != null){
							checkBoxShowGuard.setEnabled(true);
							property = graphNode.getProperty(EdgeTransitionHelper.TRANSITION_DISPLAY_GUARD);
							if(property != null){
								if(property.getValue().equals(EdgeTransitionHelper.TRANSITION_DISPLAY)){
									currentGuardAppearance = true;
								}
								else{
									currentGuardAppearance = false;
								}
							}
						}
						else{
							checkBoxShowGuard.setEnabled(false);
							currentGuardAppearance = false;
						}
						
						if(!((Transition)umlElement).getTriggers().isEmpty()){
							checkBoxShowTriggers.setEnabled(true);
							property = graphNode.getProperty(EdgeTransitionHelper.TRANSITION_DISPLAY_TRIGGERS);
							if(property != null){
								if(property.getValue().equals(EdgeTransitionHelper.TRANSITION_DISPLAY)){
									currentTriggersAppearance = true;
								}
								else{
									currentTriggersAppearance = false;
								}
							}
						}
						else{
							checkBoxShowTriggers.setEnabled(false);
							currentTriggersAppearance = false;
						}
						
						if(((Transition)umlElement).getEffect() != null){
							checkBoxShowEffect.setEnabled(true);
							property = graphNode.getProperty(EdgeTransitionHelper.TRANSITION_DISPLAY_EFFECT);
							if(property != null){
								if(property.getValue().equals(EdgeTransitionHelper.TRANSITION_DISPLAY)){
									currentEffectAppearance = true;
								}
								else{
									currentEffectAppearance = false;
								}
							}
						}
						
						checkBoxShowStereotypes.setEnabled(true);
						property = graphNode.getProperty(EdgeTransitionHelper.TRANSITION_DISPLAY_STEREOTYPES);
						if(property != null){
							if(property.getValue().equals(EdgeTransitionHelper.TRANSITION_DISPLAY)){
								currentStereotypesAppearance = true;
							}
							else{
								currentStereotypesAppearance = false;
							}
						}
						else{
							checkBoxShowStereotypes.setEnabled(false);
							currentStereotypesAppearance = false;
						}
					}
				}				
			}
			else{
				checkBoxShowName.setEnabled(false);
				checkBoxShowGuard.setEnabled(false);
				checkBoxShowEffect.setEnabled(false);
				checkBoxShowTriggers.setEnabled(false);
				checkBoxShowStereotypes.setEnabled(false);
			}
			checkBoxShowName.setSelection(currentNameAppearance);
			checkBoxShowGuard.setSelection(currentGuardAppearance);
			checkBoxShowEffect.setSelection(currentEffectAppearance);
			checkBoxShowTriggers.setSelection(currentTriggersAppearance);
			checkBoxShowStereotypes.setSelection(currentStereotypesAppearance);
			
			checkBoxShowName.addSelectionListener(showName);
			checkBoxShowGuard.addSelectionListener(showGuard);
			checkBoxShowEffect.addSelectionListener(showEffect);
			checkBoxShowTriggers.addSelectionListener(showTriggers);
			checkBoxShowStereotypes.addSelectionListener(showStereotypes);
		}		
	}
	
	/**
	 * @see com.cea.papyrus.core.ui.properties.tabbed.PropertyViewSection#dispose()
	 */
	@Override
	public void dispose(){
		super.dispose();
		if((checkBoxShowName != null) && !checkBoxShowName.isDisposed())
			checkBoxShowName.removeSelectionListener(showName);
		if((checkBoxShowGuard != null) && !checkBoxShowGuard.isDisposed())
			checkBoxShowGuard.removeSelectionListener(showGuard);
		if((checkBoxShowEffect != null) && !checkBoxShowEffect.isDisposed())
			checkBoxShowEffect.removeSelectionListener(showEffect);
		if((checkBoxShowTriggers != null) && !checkBoxShowTriggers.isDisposed())
			checkBoxShowTriggers.removeSelectionListener(showTriggers);
		if((checkBoxShowStereotypes != null) && !checkBoxShowStereotypes.isDisposed())
			checkBoxShowStereotypes.removeSelectionListener(showStereotypes);
	}
}